using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using UMC.Data;

namespace UMC.Web
{
    /// <summary>
    /// 
    /// </summary>
    public abstract class WebHandler
    {

        /// <summary>
        /// 上下文的会话
        /// </summary>
        public WebContext Context
        {
            get;
            internal set;
        }
        /// <summary>
        /// 当前处理流程
        /// </summary>
        public WebFlow Flow
        {
            get;
            internal set;
        }

        /// <summary>
        /// 提示
        /// </summary>
        /// <param name="text">文本</param>
        /// <param name="endResponse">是否结束响应返回客户端</param>

        protected void Prompt(string text, bool endResponse)
        {
            WebResponse response = this.Context.Response;
            response.ClientEvent |= WebEvent.Prompt;
            WebMeta prompt = new WebMeta();
            prompt["Text"] = text;

            response.Headers.Set("Prompt", prompt);
            if (endResponse)
            {
                this.Context.End();
            }

        }
        /// <summary>
        /// 指令对话框
        /// </summary>
        /// <param name="asyncId">对话框Id</param>
        /// <param name="model">选项模块</param>
        /// <param name="cmd">选项指令</param>
        public string AsyncDialog(String asyncId, String model, String cmd)
        {
            return AsyncDialog(asyncId, model, cmd, new WebMeta());
        }
        public string AsyncDialog(String asyncId, String model, String cmd, bool isSafe)
        {
            return AsyncDialog(asyncId, model, cmd, new WebMeta(), isSafe);
        }
        public string AsyncDialog(String asyncId, String model, String cmd, int timeout)
        {
            return AsyncDialog(asyncId, model, cmd, new WebMeta(), timeout > 0, timeout);

        }

        /// <summary>
        /// 指令对话框
        /// </summary>
        /// <param name="asyncId"></param>
        /// <param name="model"></param>
        /// <param name="cmd"></param>
        /// <param name="meta"></param>
        /// <returns></returns>
        public string AsyncDialog(String asyncId, String model, String cmd, WebMeta meta)
        {
            return this.AsyncDialog(asyncId, g =>
            {
                var uiEvent = new WebMeta();
                var id = UMC.Data.Utility.Guid(Guid.NewGuid());
                uiEvent.Put("Key", id);
                uiEvent.Put("Name", asyncId);
                uiEvent.Put("Click", new WebMeta().Put("model", model, "cmd", cmd).Put("send", meta.Put("Key", id)));
                uiEvent.Put("Submit", new WebMeta("model", this.Context.Request.Model, "cmd", this.Context.Request.Command).Put("send", this.Context.Request.Arguments));

                this.Context.Response.Headers.Put("UIEvent", uiEvent);
                this.Context.Response.ClientEvent = this.Context.Response.ClientEvent | WebEvent.UIEvent;
                this.Context.Response.End();
            });

        }
        public string AsyncDialog(String asyncId, String model, String cmd, WebMeta meta, bool isSafe)
        {
            return this.AsyncDialog(asyncId, model, cmd, meta, isSafe, 0);
        }
        public readonly static String TempKey = Utility.Guid(Guid.NewGuid());
        /// <summary>
        /// 指令对话框
        /// </summary>
        /// <param name="asyncId"></param>
        /// <param name="model"></param>
        /// <param name="cmd"></param>
        /// <param name="meta"></param>
        /// <param name="isSingle">是否开启安全模式，</param>
        /// <returns></returns>
        public string AsyncDialog(String asyncId, String model, String cmd, WebMeta meta, int timeout)
        {
            return this.AsyncDialog(asyncId, model, cmd, meta, timeout > 0, timeout);
        }
        private string AsyncDialog(String asyncId, String model, String cmd, WebMeta meta, bool isSafe, int timeout)
        {
            if (isSafe)
            {
                var value = AsyncDialog(asyncId, model, cmd, meta);
                var sign = AsyncDialog(UIDialog.KEY_DIALOG_SIGN, r => this.DialogValue($"{Utility.TimeSpan()},"));
                var nonce = sign.Substring(0, sign.IndexOf(','));
                if (timeout > 0)
                {
                    if (Utility.IntParse(nonce, 0) + timeout < Utility.TimeSpan())
                    {
                        sign = $"{Utility.TimeSpan()},";
                    }
                }
                var sn = Utility.Guid(new Guid(Utility.MD5(asyncId, TempKey, nonce, value)));

                if (sign.Contains(sn) == false)
                {
                    if (this.Context.Client.RedirectTimes >= 2)
                    {
                        this.Context.Request.Arguments.Put(UIDialog.KEY_DIALOG_SIGN, $"{sign},{sn}");
                    }
                    else
                    {
                        meta.Put("CheckValue", value);
                        this.Context.Request.Arguments.Remove(asyncId);
                        this.Context.Request.SendValues?.Remove(asyncId);
                        this.Context.Request.Headers.Remove(this.Context.Request.Command);

                        return AsyncDialog(asyncId, model, cmd, meta);
                    }

                }
                return value;

            }

            return AsyncDialog(asyncId, model, cmd, meta);


        }
        protected string AsyncDialog(string asyncId, string deValue)
        {
            return UIDialog.AsyncDialog(this.Context, asyncId, k => this.DialogValue(deValue));
        }

        protected UIDialog DialogValue(string value)
        {
            return UIDialog.ReturnValue(value);
        }

        protected UMC.Web.UIFormDialog DialogValue(WebMeta value)
        {
            return UMC.Web.UIDialog.ReturnValue(value);
        }
        /// <summary>
        /// 单值对话框
        /// </summary>
        /// <param name="asyncId"></param>
        /// <param name="callback"></param>
        /// <returns></returns>
        protected string AsyncDialog(string asyncId, Func<String, UIDialog> callback)
        {
            return UMC.Web.UIDialog.AsyncDialog(this.Context, asyncId, callback);
        }
        protected string AsyncDialog(string asyncId, Func<String, string> callback)
        {
            return UMC.Web.UIDialog.AsyncDialog(this.Context, asyncId, (v) => this.DialogValue(callback(v)));
        }
        protected string AsyncDialog(string asyncId, Action<String> action)
        {
            return UMC.Web.UIDialog.AsyncDialog(this.Context, asyncId, (a) =>
            {
                action(a);
                this.Context.End();
                return this.DialogValue("none");
            });
        }
        /// <summary>
        /// 表单对话框
        /// </summary>
        protected WebMeta AsyncDialog(Func<String, UIFormDialog> callback, string asyncId)
        {
            return UIFormDialog.AsyncDialog(this.Context, asyncId, d => callback(asyncId));
        }
        protected Action<T> AsyncAction<T>(Action<T> action)
        {
            return (t) =>
              {
                  try
                  {
                      action(t);
                  }
                  catch (WebAbortException)
                  {
                      this.Context.OutputFinish();
                  }
                  catch (Exception error)
                  {
                      this.Context.Client.Context.Error(error);
                  }

              };
        }
        /// <summary>
        /// 表单对话框
        /// </summary>
        protected WebMeta AsyncDialog(string asyncId, Func<String, UIFormDialog> callback)
        {
            return UIFormDialog.AsyncDialog(this.Context, asyncId, d => callback(asyncId));
        }
        /// <summary>
        /// 提示框,并终止响应且返回客户端
        /// </summary>
        /// <param name="text">文本</param>
        protected void Prompt(string text)
        {

            Prompt(text, true);
        }
        /// <summary>
        /// 弹出式提示框,并终止响应且返回客户端
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="text">文本</param>
        protected void Prompt(string title, string text)
        {
            this.Prompt(title, text, true);
        }
        /// <summary>
        /// 弹出式提示框
        /// </summary>
        /// <param name="title">标题</param>
        /// <param name="text">文本</param>
        /// <param name="endResponse">是否结束响应返回客户端</param>
        protected void Prompt(string title, string text, bool endResponse)
        {
            var meta = new WebMeta().Put("Type", "Prompt").Put("Title", title).Put("Text", text);

            var response = this.Context.Response;
            response.Headers.Set(EventType.AsyncDialog, meta);
            response.ClientEvent |= WebEvent.AsyncDialog | WebClient.Prompt;
            if (endResponse)
            {
                this.Context.End();
            }
        }
    }
}
